package com.att.control;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

import javax.xml.parsers.ParserConfigurationException;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.xml.sax.SAXException;

import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.IShellOutputReceiver;
import com.android.ddmlib.InstallException;
import com.android.ddmlib.RawImage;
import com.android.ddmlib.ShellCommandUnresponsiveException;
import com.android.ddmlib.TimeoutException;
import com.sun.image.codec.jpeg.JPEGCodec;

public class AttMain {

	public static int screen_port = 0;
	public static int action_port = 0;
	public static String sn = "";
	public static File configFile;
	public static int mode = 0; //0 旧模式； 1 新模式 
	public static boolean initFlag = false;
	//    /home/matthew/0160564204010019.xml
	public static void main(String[] args) {
		AttMain main = new AttMain();
		String file = main.getClass().getProtectionDomain().getCodeSource().getLocation().getFile() + "log4j.properties";
//		String file = "c:\\log4j.properties";
		PropertyConfigurator.configure(file);
        Logger logger  =  Logger.getLogger(AttMain. class );
        logger.debug("attmain start");
		CommandHandler handler = null;
		CommandHandler tempHandler = null;
		/***********************/
		if (args.length == 3) {
			 logger.debug("旧模式启动");
			 mode = 0;
			screen_port = Integer.valueOf(args[0]);
			action_port = Integer.valueOf(args[1]);
			sn = args[2];
			logger.debug("screen:" + screen_port + "-action:" + action_port + "-sn:" + sn);
			try {
				AndroidProxy.getInstance().connectionWithMonkey();
			} catch (InterruptedException e) {
				e.printStackTrace();
				logger.error(e);
			} catch (TimeoutException e) {
				e.printStackTrace();
			} catch (AdbCommandRejectedException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			handler = new MonkeyEventHandler();
		} else if (args.length == 4) {
			mode = 1;
			 logger.debug("新模式启动");
			screen_port = Integer.valueOf(args[0]);
			action_port = Integer.valueOf(args[1]);
			sn = args[2];
			configFile = new File(args[3]);
			logger.debug("screen:" + screen_port + "-action:" + action_port + "-sn:" + sn + "-file:" + configFile);
			if (!configFile.exists()) {
				logger.debug("config file not exist");
				logger.debug("attcontrol exit");
				System.out.println("config file not exist");
				return;
			} else {
				try {
					AndroidProxy.getInstance().connection();
					FileInputStream in = new FileInputStream(configFile);
					DeviceEventConfig config = new DeviceEventConfig();
					config.parseConfig(in);
					handler = new SendEventHandler();
					((SendEventHandler)handler).setConfig(config);
				} catch (InterruptedException e) {
					e.printStackTrace();
					logger.error(e);
				} catch (FileNotFoundException e) {
					e.printStackTrace();
					logger.error(e);
				} catch (ParserConfigurationException e) {
					e.printStackTrace();
					logger.error(e);
				} catch (SAXException e) {
					e.printStackTrace();
					logger.error(e);
				} catch (IOException e) {
					e.printStackTrace();
					logger.error(e);
				}
			}
		}else {
			System.out.println("params error");
			logger.error("params error");
			return;
		}
		System.out.println("attcontrol has ran");
		ScreenCapture sc = new ScreenCapture(screen_port);
		Scanner scanner = new Scanner(System.in);
		while (true) {
			String cmd = scanner.nextLine();
			if ("start screen capture service".equals(cmd)) {
				logger.debug("start screen capture service");
				sc.startService();
				continue;
			}
			if (cmd.split(" ")[0].equals("press")) {
				logger.debug("press");
				String[] params = cmd.split(" ");
				String keycode = params[1];
				handler.press(keycode);
				continue;
			}
			if (cmd.contains("drag")) {
				logger.debug("drag");
				String[] params = cmd.split(" ");
				String startx = params[1];
				String starty = params[2];
				String endx = params[3];
				String endy = params[4];
				String steps = params[5];
				String ms = params[6];
				handler.drag(startx, starty, endx, endy, steps, ms);
				continue;
			}
//			if (cmd.contains("touch down&up")) {
//				String[] params = cmd.split(" ");
//				String x = params[2];
//				String y = params[3];
//				try {
//					injector.touchDown(Integer.valueOf(x), Integer.valueOf(y));
//					Thread.sleep(150);
//					injector.touchUp(Integer.valueOf(x), Integer.valueOf(y));
//				} catch (NumberFormatException e) {
//					e.printStackTrace();
//				} catch (IOException e) {
//					e.printStackTrace();
//					try {
//						injector.quit();
//					} catch (IOException e1) {
//						e1.printStackTrace();
//					}
//				} catch (Exception e) {
//					e.printStackTrace();
//				}
//				continue;
//			}
//			if (cmd.contains("touch down")) {
//				String[] params = cmd.split(" ");
//				String x = params[2];
//				String y = params[3];
//				try {
//					injector.touchDown(Integer.valueOf(x), Integer.valueOf(y));
//				} catch (NumberFormatException e) {
//					e.printStackTrace();
//				} catch (IOException e) {
//					e.printStackTrace();
//					try {
//						injector.quit();
//					} catch (IOException e1) {
//						e1.printStackTrace();
//					}
//				}
//				continue;
//			}
//			if (cmd.contains("touch move")) {
//				String[] params = cmd.split(" ");
//				String x = params[2];
//				String y = params[3];
//				try {
//					injector.touchMove(Integer.valueOf(x), Integer.valueOf(y));
//				} catch (NumberFormatException e) {
//					e.printStackTrace();
//				} catch (IOException e) {
//					e.printStackTrace();
//					try {
//						injector.quit();
//					} catch (IOException e1) {
//						e1.printStackTrace();
//					}
//				}
//				continue;
//			}
//			if (cmd.contains("touch up")) {
//				String[] params = cmd.split(" ");
//				String x = params[2];
//				String y = params[3];
//				try {
//					injector.touchUp(Integer.valueOf(x), Integer.valueOf(y));
//				} catch (NumberFormatException e) {
//					e.printStackTrace();
//				} catch (IOException e) {
//					e.printStackTrace();
//					try {
//						injector.quit();
//					} catch (IOException e1) {
//						e1.printStackTrace();
//					}
//				}
//				continue;
//			}
			if (cmd.contains("touch")) {
				logger.debug("touch");
				String[] params = cmd.split(" ");
				String x = params[1];
				String y = params[2];
				handler.touch(x, y);
				continue;
			}
			if (cmd.contains("longpress")) {
				logger.debug("longpress");
				String[] params = cmd.split(" ");
				if (params.length == 3) {
					String x = params[1];
					String y = params[2];
					handler.longpress(x, y);
				} else {
					String keycode = params[1];
					handler.physicsLongpress(keycode);
				}
				continue;
			}
//			if (cmd.contains("photos")) {
//				String[] params = cmd.split(" ");
//				String path = params[1];
//				try {
//					injector.takePhoto(path);
//				} catch (IOException e) {
//					e.printStackTrace();
//					try {
//						injector.quit();
//					} catch (IOException e1) {
//						e1.printStackTrace();
//					}
//				}
//			}
			if (cmd.contains("type")) {
				logger.debug("type");
				String[] params = cmd.split(" ");
				StringBuilder sb = new StringBuilder();
				for (int i = 1; i < params.length; i++) {
					sb.append(params[i]);
				}
//				String text = params[1];
				if (mode == 0) {
					handler.type(sb.toString());
				} else if (mode == 1) {
					if (!initFlag) {
						try {
							AndroidProxy.getInstance().connectionWithMonkey();
						} catch (InterruptedException e) {
							e.printStackTrace();
						} catch (TimeoutException e) {
							e.printStackTrace();
						} catch (AdbCommandRejectedException e) {
							e.printStackTrace();
						} catch (IOException e) {
							e.printStackTrace();
						}
						tempHandler = new MonkeyEventHandler();
						initFlag = true;
					}
					tempHandler.type(sb.toString());
				}
			}
			if (cmd.contains("snapshot")) {
				String[] params = cmd.split(" ");
				String path = params[1];
				logger.debug("snapshot:" + path);
				try {
					RawImage raw = AndroidProxy.getInstance().getDevice().getScreenshot();
					BufferedImage image = new BufferedImage(raw.width, raw.height,
							BufferedImage.TYPE_INT_RGB);
					int index = 0;
					int indexInc = raw.bpp >> 3;
					for (int y = 0; y < raw.height; y++) {
						for (int x = 0; x < raw.width; x++, index += indexInc) {
							int value = raw.getARGB(index);
							image.setRGB(x, y, value);
						}
					}
					FileOutputStream fos = new FileOutputStream(path);
					JPEGCodec.createJPEGEncoder(fos).encode(image);
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (TimeoutException e) {
					e.printStackTrace();
				} catch (AdbCommandRejectedException e) {
					e.printStackTrace();
				}
			}
			if (cmd.contains("installAPK")) {
				String[] params = cmd.split(" ");
				String pkgName = params[1];
				String apkPath = params[2];
				try {
					AndroidProxy.getInstance().getDevice().uninstallPackage(pkgName);
					AndroidProxy.getInstance().getDevice().installPackage(apkPath, true);
//					System.out.println(uninstall + "-----" + install);
					System.out.println("<installAPK>success</installAPK>");
				} catch (InstallException e) {
//					e.printStackTrace();
					System.out.println("<installAPK>error</installAPK>");
				}
			}
//			if ("quit monkey".equals(cmd)) {
//				try {
//					injector.quit();
//				} catch (IOException e) {
//					e.printStackTrace();
//				}
//				continue;
//			}
			if (cmd.contains("startActivity")) {
				String[] params = cmd.split(" ");
				String startcmd = "am start -n " + params[1] + "\n";
				try {
					AndroidProxy.getInstance().getDevice().executeShellCommand(startcmd, new IShellOutputReceiver() {
						
						@Override
						public boolean isCancelled() {
							return false;
						}
						
						@Override
						public void flush() {
						}
						
						@Override
						public void addOutput(byte[] b, int offset, int length) {
							System.out.println("<startActivity>success</startActivity>");
						}
					});
				} catch (IOException e) {
					e.printStackTrace();
				} catch (TimeoutException e) {
					e.printStackTrace();
				} catch (AdbCommandRejectedException e) {
					e.printStackTrace();
				} catch (ShellCommandUnresponsiveException e) {
					e.printStackTrace();
				}
				continue;
			}
			if (cmd.contains("apkIsInstall")) {
				String[] params = cmd.split(" ");
				String startcmd = "cd /data/data/" + params[1] + "\n";
				try {
					AndroidProxy.getInstance().getDevice().executeShellCommand(startcmd, new IShellOutputReceiver() {
						
						@Override
						public boolean isCancelled() {
							return false;
						}
						
						@Override
						public void flush() {
						}
						
						@Override
						public void addOutput(byte[] b, int offset, int length) {
							String str = new String(b, 0, length);
							if (str != null && !"".equals(str)) {
								if (str.contains("can't")) {
									System.out.println("<apkIsInstall>false</apkIsInstall>");
								}
							} else {
								System.out.println("<apkIsInstall>true</apkIsInstall>");
							}
						}
					});
				} catch (IOException e) {
					e.printStackTrace();
				} catch (TimeoutException e) {
					e.printStackTrace();
				} catch (AdbCommandRejectedException e) {
					e.printStackTrace();
				} catch (ShellCommandUnresponsiveException e) {
					e.printStackTrace();
				}
				continue;
			}
			if ("quit".equals(cmd)) {
				logger.debug("quit");
				handler.quit();
				System.exit(0);
			}
		}
		/***********************/
	}

}
